package Buildings;
import Interfaces.*;
import java.util.Iterator;
public class SynchronizedFloor implements Floor{
    private Space []floor;
    private class myIterator implements Iterator {

        private int index = -1;
        public boolean hasNext() {
            return index + 1 < getHowMuchSpaceInFloor();
        }
        public Space next() {
            index += 1;
            if (index < floor.length) {
                return floor[index];
            } else {
                return null;
            }
        }
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
    @Override
    public java.util.Iterator iterator() {
        return new myIterator();
    }
    @Override
    synchronized public int getHowMuchSpaceInFloor(){
        return floor.length;
    }
    @Override
    synchronized public double getHowMuchAreaInFloor(){
        double s=0;
        for(int i=0;i<floor.length;i++){
            s+=floor[i].getHowMuchArea();
        }
        return s;
    }
    @Override
    synchronized public int getHowMuchRoomsInFloor(){
        int n=0;
        for(int i=0;i<floor.length;i++){
            n+=floor[i].getHowMuchArea();
        }
        return n;
    }
    @Override
    synchronized public Space[] getMassSpacesInFloor(){
        return floor;
    }
    @Override
    synchronized public Space getSpaceInFloor(int n){
        if(n>=0 && n<floor.length){
            return floor[n];
        }
        return null;
    }
    @Override
    synchronized public void setSpaceInFloor(int i, Space s) {
        if (i >= 0 && i < floor.length) {
            floor[i] = (Space) s.clone();
        } else {
            System.out.println("Неправильный номер!");
        }
    }
    @Override
    synchronized public void addSpaceInFloor(int i, Space s) {
        if (i >= 0 && i <=floor.length) {
            //Space []newFloor=new Space[floor.length+1];
            Space []newFloor=new Space[getHowMuchSpaceInFloor()+1];//синхрон
            if(i==0){//для начала
                newFloor[0]=(Space)s.clone();
                int k=0;
                for(int j=1;j<newFloor.length;j++,k++){
                    newFloor[j]=getSpaceInFloor(k);//синхрон
                }
                floor=newFloor;
                return;
            }
            if(i==floor.length){//для конца
                for(int j=0;j<getHowMuchSpaceInFloor();j++){//синхр
                    newFloor[j]=getSpaceInFloor(j);//синхр
                }
                newFloor[i]=(Space)s.clone();
                floor=newFloor;
                return;
            }
            for(int j=0;j<i;j++){//для середины
                newFloor[j]=getSpaceInFloor(j);//синхр
            }
            newFloor[i]=(Space)s.clone();
            int k=i+1;
            for(int j=i;j<getHowMuchSpaceInFloor();j++){//синхр
                newFloor[k]=getSpaceInFloor(j);//синхр
                k++;
            }
            floor=newFloor;
        } else {
            System.out.println("Неправильный номер для этажа!");
        }
    }
    @Override
    synchronized public void delSpaceInFloor(int i) {
        if (i >= 0 && i <floor.length) {
            Space []newFloor=new Space[getHowMuchSpaceInFloor()-1];//синхр
            if(i==0){
                for(int j=1;j<getHowMuchSpaceInFloor();j++){//синхрон
                    newFloor[j-1]=getSpaceInFloor(j);//синхрон
                }
                floor=newFloor;
                return;
            }
            if(i==floor.length-1){
                for(int j=0;j<getHowMuchSpaceInFloor()-1;j++){//синхрон
                    newFloor[j]=getSpaceInFloor(j);//синхрон
                }
                floor=newFloor;
                return;
            }
            for(int j=0;j<i;j++){
                newFloor[j]=getSpaceInFloor(j);//синхрон
            }
            for(int j=i+1;j<getHowMuchSpaceInFloor();j++){//синхрон
                newFloor[j]=getSpaceInFloor(j);//синхрон
            }
            floor=newFloor;   
        } else {
            System.out.println("Неправильный номер! Квартиры с таким номером не существует.");
        }
    }
    @Override
    synchronized public Space getBestSpace() {
        double s = 0;
        int j = 0;
        for (int i = 0; i < getHowMuchSpaceInFloor(); i++) {//синхрон
                if (s < floor[i].getHowMuchArea()) {
                    j = i;
                    s = floor[i].getHowMuchArea();
                }
        }
        if (s != 0) {
            return floor[j];
        }
        return null;
    }
    @Override
    synchronized public Object clone() {
        Space []massForClone=new Space[floor.length];
        for(int i=0;i<getHowMuchSpaceInFloor();i++){
            massForClone[i]=(Space)floor[i].clone();
        }
        return new SynchronizedFloor (massForClone);
    }
    @Override
    synchronized public String toString() {
        StringBuilder s = new StringBuilder();
        s.append(" этаж (синхр) \n");
        for (int i = 0; i < getHowMuchSpaceInFloor(); i++) {
            s.append((getSpaceInFloor(i).toString()));
        }
        s.append("\n");
        return s.toString();
    }
    @Override
    synchronized public boolean equals(Object o) {
        boolean answer = false;
        if (o.getClass() == this.getClass()) {
            if (((SynchronizedFloor) o).getHowMuchSpaceInFloor() == this.getHowMuchSpaceInFloor()) {
                boolean key = true;
                for (int j = 0; j < getHowMuchSpaceInFloor(); j++) {
                    if (getSpaceInFloor(j).equals(((SynchronizedFloor) o).getSpaceInFloor(j)) == false) {
                        key = false;
                        break;
                    }
                }
                if (key == true)answer = true;
            }
        }
        return answer;
    }
    @Override
    synchronized public int hashCode() {
        int hash;
        hash = (Integer.bitCount(this.getHowMuchSpaceInFloor()));
        for (int i = 0; i < this.getHowMuchSpaceInFloor(); i++) {
            hash = (int) (hash ^ this.getSpaceInFloor(i).hashCode());
        }
        return hash;
    }
    SynchronizedFloor(Floor fl){
        floor=fl.getMassSpacesInFloor();
    }
    SynchronizedFloor(Space []fl){
        floor=fl;
    }
}
